package find;

/**
 * 使用位运算获取两个数中值较大的
 *
 * @author Liaorun
 */
public class GetMaxByBit {


    /**
     * @param n must be 0 or 1
     * @return 1 -> 0; 0 ->1
     */
    public static int flip(int n) {
        return n ^ 1;
    }

    /**
     * n 是非负数，返回1
     * n 是负数，返回0
     *
     * @param n
     * @return
     */
    public static int sign(int n) {
        // question: 右移就可以了为什么还要与一下
        return flip((n >> 31) & 1);
    }

    /**
     * 获取两个整数中较大的一个
     *
     * @param a
     * @param b
     * @return
     */
    public static int getMax1(int a, int b) {
        // 下一步可能发生溢出，导致结果错误
        int c = a - b;
        // a - b >= 0,scA == 1; a-b < 0, scA == 0;
        int scA = sign(c);
        // 1变0，0变1
        int scB = flip(scA);

        return a * scA + b * scB;
    }

    public static int getMax2(int a,int b) {
        int c = a -b;
        int sa = sign(a);
        int sb = sign(b);
        int sc = sign(c);
        // a和b的符号不一样 ？ 1 ： 0；
        int difSab = sa ^ sb;
        // a和b的符号一样 ？ 1 ： 0；
        int sameSab = flip(difSab);
        // 返回a的情况: 1. a和b的符号不一样 && a >= 0
        // 2. a和b的符号一样 && a - b > 0 (a在数轴的右边)
        int returnA = difSab * sa + sameSab * sc;
        int returnB = flip(returnA);

        return a * returnA + b * returnB;
    }

    public static void main(String[] args) {
        int a = -16;
        int b = 1;
        System.out.println(getMax1(a, b));
        System.out.println(getMax2(a, b));

        a = 2147483647;
        b = -2147480000;

        // wrong answer because of overflow
        System.out.println(getMax1(a, b));
        System.out.println(getMax2(a, b));
    }
}
